package cn.iocoder.yudao.module.reading.service.community;

import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.module.reading.controller.app.community.vo.common.SensitiveCheckRespVO;
import cn.iocoder.yudao.module.reading.dal.dataobject.community.CommunitySensitiveWordDO;
import cn.iocoder.yudao.module.reading.dal.mysql.community.CommunitySensitiveWordMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

/**
 * 本地敏感词检查服务实现类（备用方案）
 *
 * @author 芋道源码
 */
@Service
@Slf4j
public class LocalSensitiveWordServiceImpl implements LocalSensitiveWordService {

    @Resource
    private CommunitySensitiveWordMapper sensitiveWordMapper;

    /**
     * 敏感词缓存
     */
    private volatile Set<String> sensitiveWords = ConcurrentHashMap.newKeySet();

    @PostConstruct
    public void init() {
        refreshSensitiveWords();
    }

    @Override
    @Cacheable(value = "community:sensitive:local", key = "#content")
    public SensitiveCheckRespVO checkTextContent(String content) {
        if (StrUtil.isBlank(content)) {
            return buildSafeResult(content);
        }

        List<String> foundSensitiveWords = new ArrayList<>();
        String lowerContent = content.toLowerCase();

        // 检查是否包含敏感词
        for (String sensitiveWord : sensitiveWords) {
            if (lowerContent.contains(sensitiveWord.toLowerCase())) {
                foundSensitiveWords.add(sensitiveWord);
            }
        }

        SensitiveCheckRespVO result = new SensitiveCheckRespVO();
        result.setHasSensitive(!foundSensitiveWords.isEmpty());
        result.setSensitiveWords(foundSensitiveWords);
        
        if (result.getHasSensitive()) {
            result.setFilteredContent(filterSensitiveContent(content, foundSensitiveWords));
        } else {
            result.setFilteredContent(content);
        }

        return result;
    }

    @Override
    @CacheEvict(value = "community:sensitive:local", allEntries = true)
    public void refreshSensitiveWords() {
        try {
            List<CommunitySensitiveWordDO> words = sensitiveWordMapper.selectList(
                    CommunitySensitiveWordDO::getIsActive, true);

            sensitiveWords = words.stream()
                    .map(CommunitySensitiveWordDO::getWord)
                    .collect(Collectors.toSet());

            log.info("[refreshSensitiveWords][刷新敏感词缓存完成] count: {}", sensitiveWords.size());
        } catch (Exception e) {
            log.error("[refreshSensitiveWords][刷新敏感词缓存失败]", e);
        }
    }

    /**
     * 构建安全的检查结果
     */
    private SensitiveCheckRespVO buildSafeResult(String content) {
        SensitiveCheckRespVO result = new SensitiveCheckRespVO();
        result.setHasSensitive(false);
        result.setSensitiveWords(new ArrayList<>());
        result.setFilteredContent(content);
        return result;
    }

    /**
     * 过滤敏感内容
     */
    private String filterSensitiveContent(String content, List<String> sensitiveWords) {
        String filteredContent = content;
        for (String word : sensitiveWords) {
            filteredContent = filteredContent.replaceAll("(?i)" + word, "***");
        }
        return filteredContent;
    }

}
